import { getToken, setToken, removeToken } from '@/utils/auth'//取token封装的函数
// 知识点13：为何本地存token，不直接使用本地token（在请求拦截器里）
// 为何多次一举，还要在vuex同步一份
// 本地也可以去拿，也可以想vuex一样共享
// 答案：vuex是存在内存里的，取值更快，浏览器本地储存室是存在磁盘里（持久化）操作磁盘比较慢

import { loginAPI, getUserProfileAPI, getUserPhotoAPI } from '@/api'
import { resetRouter } from '@/router'
const getDefaultState = () => {
  return {
    //设置token值
    token: getToken(),
    // 获取用户信息===并保存一下信息id
    userInfo: JSON.parse(localStorage.getItem('userInfo')) || {}
    // 前面本地取值如果是null,那么userInfo，任何属性直接报错，终止代码执行
    // null||{}相当于if的意思，前面没值，要给userInfo一个空对象，因为getters里面有值
    // userInfo.companyId防止他取值错误，空对象.companyId返回undefined不会导致代码语法错报错
  }
}
const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  // 存token
  SET_TOKEN: (state, newToken) => {
    state.token = newToken
    setToken(newToken)//新值存放
  },
  // 删除token
  DEL_TOKEN: (state) => {
    state.token = ''
    removeToken()
  },
  // 存用户信息
  SET_USER: (state, value) => {
    state.userInfo = value
    // 把信息用户信息的id存在localStorage
    localStorage.setItem('userInfo', JSON.stringify(value))//用户信息存入本地

  },
  // 删除用户信息
  DEL_USER: (state) => {
    state.userInfo = {}
    // 删除用户信息
    localStorage.removeItem('userInfo')
  }
}

const actions = {
  // 大神写法登录逻辑===针对token
  async loginActions ({ commit }, value) {
    // 用try+catch写
    // try {
    //   const res = await loginAPI(value)
    //   // 响应拦截器里面response.data里，所以这里拿到的是后台返回数据对象
    //   // res.data就是token，
    //   commit('SET_TOKEN', res.data)//token依旧保持到上面vuex中

    //   return res//逻辑页面登录页那边接收的也不是数组
    // } catch (err) {
    //   // 外面也有try+catch
    //   // actions本身返回的也是一个Promise对象
    //   // 逻辑页面也得用await取值
    //   return Promise.reject(err)
    //   // 因为这里没有resolve和reject所以要用Promise.reject()
    // }
    // 大神写法
    const [err, res] = await loginAPI(value)
    // 我们只需要token, 保存到上面的vuex中
    if (!err) commit('SET_TOKEN', res.data)
    // 逻辑页面还在接收数组, 外面写成功/失败的逻辑, 所以这里要把数组返回出去
    // return到actions调用的地方(login/index.vue)
    return [err, res]
  },
  // 获取用户信息
  // 默认第一个形参stoe 以前store.commit()
  // {commit} = store对象的解构赋值, 把store对象里的commit方法直接赋予给了左侧的{}里的commit变量
  async getUserInfoActions ({ commit }) {

    const res = await getUserProfileAPI()//获取用户信息
    // console.log(res)

    // commit('SET_USER', res.data)//存到上面的用户信息
    const photo = await getUserPhotoAPI(res.data.userId)//获取用户信息id
    // console.log(photo)
    // res.data和photo.data的2个对象里的key+value合并成一个对象
    // 赋予给userInfo保存（我们要的数据来自于2个接口对象中）
    commit('SET_USER', { ...res.data, ...photo.data })
  },
  // 退出登录==此项目退出登录并没有接口
  async delActions ({ commit }) {
    // 删除vuex和本地token
    // 先清除本地token，然后在重置state（因为上面重置state还会去本地取一次）
    // 跳转不了，多想想路由守+token的事情

    // commit-触发mutations方法（固定）
    // dispatch-触发actions方法（固定）
    commit('app/RESET_ASYNCROUTE', null, { root: true }) // 因为重新登录后要重新计算动态路由规则数组
    commit('DEL_USER')//删除user信息
    commit('DEL_TOKEN')//删除token
    commit('RESET_STATE')//清除用户信息退出的时候
    resetRouter()//重置路由


  }


}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
